package com.ecoolex.ying.space.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.pojo.Sortings;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.io.HttpUtil;
import com.ecoolex.ying.space.core.dao.PushMessageDAO;
import com.ecoolex.ying.space.entity.PushMessage;
import com.ecoolex.ying.space.entity.PushMessage.Column;
import com.ecoolex.ying.space.entity.PushMessageExample;
import com.ecoolex.ying.space.entity.PushMessageExample.Criteria;
import com.ecoolex.ying.space.entity.PushMessageReadState;

import java.time.Instant;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PushMessageManager {
	
    @Autowired
    private PushMessageDAO dao;
    
    @Autowired
    private PushMessageReadStateManager pushMessageReadStateManager;
    
    public void verify(PushMessage record) {
    	BizAssert.isTrue(Check.notNullOrTrimEmpty(record.getTitle()), ResultCode.VERIFY.build(10), "推送标题为空");
    	BizAssert.isTrue(Check.notNullOrTrimEmpty(record.getContent()), ResultCode.VERIFY.build(11), "推送内容为空");
    	if(Check.notNullOrTrimEmpty(record.getLink())) {
    		BizAssert.isTrue(HttpUtil.isHttpUrl(record.getLink()), ResultCode.VERIFY.build(12), "跳转链接不合法");
    	}
    	BizAssert.isTrue(Check.notNull(record.getPushTime()), ResultCode.VERIFY.build(13), "推送时间为空");
    }
    
    public PushMessage getById(Integer id) {
    	return dao.selectByPrimaryKeyWithLogicalDelete(id, PushMessage.NOT_DELETED);
    }
    
    public Pagination<PushMessage> query(String title, Date startTime, Date endTime, Sorting[] sorts, Page page){
    	PushMessageExample example = new PushMessageExample();
    	Criteria criteria = example.createCriteria();
    	if(Check.notNullOrTrimEmpty(title)) {
    		criteria.andTitleLike("%"+title+"%");
    	}
    	if(Check.notNull(startTime) && Check.notNull(endTime)) {
    		criteria.andPushTimeBetween(startTime, endTime);
    	}
    	criteria.andDeletedEqualTo(PushMessage.NOT_DELETED);
    	example.orderBy(Sortings.builder(sorts).verify(Column::valueOf).toSql());
		example.setOffset(page.getFirstIndex());
		example.setRows(page.getPageSize());

		return Pagination.create(page, dao.countByExample(example), () -> dao.selectByExample(example));
    }
    
    public Pagination<PushMessage> queryForH5(Date now, Page page){
    	
    	return Pagination.create(page, dao.countByDate(now), () -> dao.queryByDate(now, page));
    }
    
    public Pagination<PushMessage> getByReleaseUserIdForH5(Integer releaseUserId,Page page) {
    	PushMessageExample example = new PushMessageExample();
    	Criteria criteria = example.createCriteria();
    	criteria.andReleaseUserIdEqualTo(releaseUserId).andPushTimeLessThanOrEqualTo(Date.from(Instant.now())).andDeletedEqualTo(PushMessage.NOT_DELETED);
		example.setOffset(page.getFirstIndex());
		example.setRows(page.getPageSize());
		example.orderBy(Column.pushTime.desc());
    	return Pagination.create(page, dao.countByExample(example),() -> dao.selectByExample(example));
    }
    
    /**
     * 用户未读推送数量统计
     * @param userId
     * @return
     */
    public Integer unreadCount(Integer readUserId,Integer releaseUserId) {
    	PushMessageExample example = new PushMessageExample();
    	Criteria criteria = example.createCriteria();
    	//获取最新读取时间
    	PushMessageReadState pushMessageReadState = pushMessageReadStateManager.getByReadUserId(readUserId,releaseUserId);
    	if(Check.notNull(pushMessageReadState)) {
    		Date newReadTime = pushMessageReadState.getNewReadTime();
    		criteria.andReleaseUserIdEqualTo(releaseUserId).andPushTimeGreaterThan(newReadTime).andPushTimeLessThanOrEqualTo(Date.from(Instant.now())).andDeletedEqualTo(PushMessageReadState.NOT_DELETED);
    	}else {
    		criteria.andReleaseUserIdEqualTo(releaseUserId).andPushTimeLessThanOrEqualTo(Date.from(Instant.now())).andDeletedEqualTo(PushMessageReadState.NOT_DELETED);
    	}
    	List<PushMessage> pushMessageList = dao.selectByExample(example);
    	return pushMessageList.size();
    }
    
    public PushMessage add(PushMessage record,String createUser) {
    	verify(record);
    	
    	record.setDeleted(PushMessage.NOT_DELETED);
    	record.setCreateUser(createUser);
    	record.setCreateTime(Date.from(Instant.now()));
    	record.setUpdateUser(createUser);
    	record.setUpdateTime(Date.from(Instant.now()));
    	dao.insert(record);
    	
    	return record;
    }
    
    public PushMessage edit(PushMessage record,String updateUser) {
    	verify(record);
    	BizAssert.isTrue(record.getPushTime().after(Date.from(Instant.now())), ResultCode.VERIFY.build(10), "无法编辑");
    	record.setUpdateUser(updateUser);
    	record.setUpdateTime(Date.from(Instant.now()));
    	dao.updateByPrimaryKeySelective(record, Column.excludes(Column.deleted,Column.createUser,Column.createTime));
    	return record;
    }
    
    public void delete(PushMessage record,String updateUser) {
    	record.setDeleted(PushMessage.IS_DELETED);
    	record.setUpdateUser(updateUser);
    	record.setUpdateTime(Date.from(Instant.now()));
    	dao.updateByPrimaryKeySelective(record, Column.deleted,Column.updateUser,Column.updateTime);
    }
}